package com.xbongbong.util;

import com.xbongbong.formula.constant.Constant;
import com.xbongbong.paas.domain.entity.ext.FieldPermissionEntityExt;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.product.BusinessProductCompareEnum;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/10/08 17:09
 */
public class ProcessUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProcessUtil.class);

    /**
     * 异或的解释处理
     * @param explainList
     * @param fieldPermissionMap
     * @param businessType
     * @param workflowTag 代表是否是工作流业务 true:是；false：否
     * @return
     */
    public static List<FieldAttrEntity> xorExplainListByFieldPermission(List<FieldAttrEntity> explainList, Map<String, FieldPermissionEntityExt> fieldPermissionMap,
                                                                        Integer businessType, boolean workflowTag, UserVO loginUser) {
        List<FieldAttrEntity> headList = new ArrayList<>();
        //需要处理的几个工作流放出关联产品字段的业务
        List<Integer> workflowProductBusList = BusinessProductCompareEnum.getProductHandleBusList();
        boolean shouldHanldTag = workflowProductBusList.contains(businessType) && workflowTag;
        try {
            for (FieldAttrEntity item : explainList) {
                // 小鲍说分割线和描述文本必定显示
                if (Objects.equals(item.getFieldType(), FieldTypeEnum.SEPARATOR.getType()) || Objects.equals(item.getFieldType(), FieldTypeEnum.MEMO.getType())) {
                    headList.add(item);
                    continue;
                }
                boolean isPaasField = Objects.equals(item.getIsRedundant(), 1);
                if(fieldPermissionMap.containsKey(item.getAttr())) {
                    FieldPermissionEntityExt fieldPermissionEntityExt = fieldPermissionMap.get(item.getAttr());
                    if (Objects.equals(1, fieldPermissionEntityExt.getEditable()) && (Objects.equals(item.getEditable(), 1) || isPaasField)) {
                        item.setEditable(1);
                    } else {
                        item.setEditable(0);
                        if (Objects.equals(item.getFieldType(), FieldTypeEnum.SINGLE_SUB_FORM.getType())) {
                            List<? extends FieldAttrEntity> subExplainList = item.getSubForm().getItems();
                            subExplainList.forEach(subItem -> subItem.setEditable(0));
                            item.getSubForm().setItems(subExplainList);
                        }
                    }
                    if(Objects.equals(1, fieldPermissionEntityExt.getVisible())){
                        if(FieldTypeEnum.SUB_FORM.getType().equals(item.getFieldType())
                                || FieldTypeEnum.CONTACT_NUMBER.getType().equals(item.getFieldType())
                                || (Objects.equals(item.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType()) && shouldHanldTag)){
                            FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
                            BeanUtil.copyProperties(item, fieldAttrEntity);
                            List<? extends FieldAttrEntity> subExplainList = item.getSubForm().getItems();
                            List<FieldAttrEntity> fieldList = new ArrayList<>(subExplainList.size());
                            //需要处理的工作流业务CRM模块的关联产品字段放出来需求，上线的时候fieldPermissionMap可能为空，所以这边需要做一下兼容处理
                            boolean trueHandleTag = Objects.equals(item.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType()) && shouldHanldTag;
                            if (trueHandleTag) {
                                handleDefaultFieldPermissionMap(businessType, fieldPermissionMap, item);
                            }
                            subExplainList.forEach((subItem)->{
                                // 字段回收站逻辑特殊处理
                                if (Objects.equals(item.getIsOpen(), 2)) {
                                    item.setVisible(0);
                                }
                                String key = item.getAttr()+"."+subItem.getAttr();
                                boolean isSubPaasField = Objects.equals(item.getIsRedundant(), 1);
                                if(fieldPermissionMap.containsKey(key)){
                                    if (trueHandleTag) {
                                        //工作流几个特殊业务放开
                                        if (Objects.equals(fieldPermissionMap.get(key).getEditable(), 1)) {
                                            subItem.setEditable(1);
                                        }else {
                                            subItem.setEditable(0);
                                        }
                                    }else {
                                        if(Objects.equals(fieldPermissionMap.get(key).getEditable(), 1) && (Objects.equals(item.getEditable(), 1) || isSubPaasField)){
                                            subItem.setEditable(1);
                                        } else {
                                            subItem.setEditable(0);
                                        }
                                    }
                                    if(Objects.equals(fieldPermissionMap.get(key).getVisible(), 1)){
                                        fieldList.add(subItem);
                                    } else {
                                        subItem.setVisible(0);
                                        fieldList.add(subItem);
                                    }
                                }
                            });
                            fieldAttrEntity.getSubForm().setItems(fieldList);

                            //启用了电话掩码的电话字段在审批处不可见 该不可见权限大于 表单设计页和流程设计处权限
                            if (ExplainUtil.isOpenTelephoneMask(fieldAttrEntity, loginUser)) {
                                fieldAttrEntity.setVisible(0);
                            }

                            headList.add(fieldAttrEntity);
                        } else {
                            //客户的审批，联系人的编辑权限先不放开
                            if(Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())
                                    && Objects.equals(item.getAttr(), CustomerManagementEnum.ADD_CONTACT.getAttr())){
                                item.setEditable(Constant.ZERO);
                            }
                            headList.add(item);
                        }
                    } else {
                        item.setVisible(0);
                        headList.add(item);
                    }
                } else {
                    headList.add(item);
                }
            }
        }catch (Exception e) {
            LOGGER.error("获取字段权限出错：", e);
        }
        return headList;
    }

    /**
     * 处理审批中默认的节点的表单字段权限
     *
     * @param businessType
     * @param fieldPermissionMap
     * @param fieldPermissionMap
     */
    public static void handleDefaultFieldPermissionMap(Integer businessType, Map<String, FieldPermissionEntityExt> fieldPermissionMap,
                                                       FieldAttrEntity productAttr) throws XbbException {
        List<String> unEditableFieldList = BusinessProductCompareEnum.getAllUnEditableFieldList(businessType);
        String prefix = productAttr.getAttr();
        List<? extends FieldAttrEntity> itemList = productAttr.getSubForm().getItems();
        Integer productEditable = productAttr.getEditable();
        Integer productVisible = productAttr.getVisible();
        for (FieldAttrEntity fieldAttrEntity : itemList) {
            String key = fieldAttrEntity.getAttr();
            String finalKey = prefix + "." + key;
            if (!fieldPermissionMap.containsKey(finalKey)) {
                Integer editable = productEditable;
                if (unEditableFieldList.contains(key)) {
                    editable = BasicConstant.ZERO;
                }
                fieldPermissionMap.put(finalKey, new FieldPermissionEntityExt(key, fieldAttrEntity.getFieldType(), editable, productVisible, BasicConstant.ZERO));
            }
        }
    }
}
